package com.zfzs.post.service.impl;

import com.zfzs.post.exception.BadRequestException;
import com.zfzs.post.model.dto.MineBenefitDetailDTO;
import com.zfzs.post.model.vo.activ.ActivListVO;
import com.zfzs.post.model.vo.activ.MineActivHeadVO;
import com.zfzs.post.modules.agent.service.dto.AgentDTO;
import com.zfzs.post.modules.common.service.AgentContactService;
import com.zfzs.post.modules.common.service.AgentTreeService;
import com.zfzs.post.modules.flow.domain.FlowActiv;
import com.zfzs.post.modules.flow.domain.OtherIncome;
import com.zfzs.post.modules.flow.service.FlowActivService;
import com.zfzs.post.modules.flow.service.OtherIncomeService;
import com.zfzs.post.service.FlowService;
import com.zfzs.post.service.JwtUserDetailsService;
import com.zfzs.post.utils.DateStrUtils;
import com.zfzs.post.utils.MathUtils;
import com.zfzs.post.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* 流水接口实现类
* @author: ck
* @create: 2019/9/9/17:06
**/
@Service
public class FlowServiceImpl implements FlowService {

    @Autowired
    private OtherIncomeService otherIncomeService;

    @Autowired
    private FlowActivService flowActivService;

    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;

    @Autowired
    private AgentContactService agentContactService;


    @Override
    public BigDecimal getSumOtherIncome(Long agentId) {
        List<OtherIncome> incomeList = otherIncomeService.findByAgentId(agentId);
        BigDecimal reduce = incomeList.stream()
                .map(OtherIncome::getAmount)
                .map(e -> new BigDecimal(e))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return reduce;
    }

    @Override
    public BigDecimal getSumActivIncome(Long agentId) {
        List<FlowActiv> flowActivs=flowActivService.findByAgentId(agentId);
        return flowActivs.stream().map(FlowActiv::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
    }

    @Override
    public Map<String, Object> getMineActivDetail(MineBenefitDetailDTO dto) {

        boolean startFlag= dto.getStartDate()==null;
        boolean endFlag= dto.getEndDate()==null;

        if(startFlag!=endFlag){
            throw new BadRequestException("起止时间必须同时选择");
        }
        AgentDTO agentInfo = jwtUserDetailsService.getAgentInfo();

        MineActivHeadVO activHead = getMineActivHead(agentInfo.getId(), dto.getStartDate(), dto.getEndDate(),agentInfo.getChannelId());
        List<ActivListVO> activList = getMineActivList(agentInfo.getId(), dto.getStartDate(), dto.getEndDate(), dto.getPageNum());

        Map<String,Object> result=new HashMap<>();
        result.put("activHead",activHead);
        result.put("activList",activList);
        return result;
    }

    List<ActivListVO> getMineActivList(Long agentId,String startDate,String endDate,Integer pageNum){
        List<Map<String,Object>> infoList = flowActivService.findInfoList(agentId, startDate, endDate, pageNum);

        List<ActivListVO> list=new ArrayList<>();
        List<String> strings = infoList.stream().map(e ->DateStrUtils.formatDate( DateStrUtils.parseDate(e.get("createTime").toString(),DateStrUtils.Y_M_D),DateStrUtils.Y_M_D)).collect(Collectors.toList());
        HashSet h = new HashSet(strings);
        strings.clear();
        strings.addAll(h);

        for (String string : strings) {

            List<Map<String,Object>> collect = infoList.stream().filter(e -> e.get("createTime").toString().equals(string)).collect(Collectors.toList());
            BigDecimal dateAmount = infoList.stream().filter(e -> DateStrUtils.formatDate( DateStrUtils.parseDate(e.get("createTime").toString(),DateStrUtils.Y_M_D),DateStrUtils.Y_M_D).equals(string)).map(e -> e.get("amount").toString()).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
            ActivListVO v=new ActivListVO();
            v.setDate(string);
            v.setList(collect);
            v.setDateAmount(MathUtils.formatToNumber(dateAmount));
            list.add(v);
        }
        return list;
    }


    @Override
    public MineActivHeadVO getMineActivHead(Long agentId, String startDate, String endDate,Long channelId) {
        MineActivHeadVO v=new MineActivHeadVO();

        List<FlowActiv> list=flowActivService.findByOwnerActiv(agentId,startDate,endDate);

        BigDecimal selfAmount=list.stream().map(FlowActiv::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);

        v.setSelfAcitvCount(list.size());
        v.setSelfActivAmount(MathUtils.formatToNumber(selfAmount));

        List<FlowActiv> totalList = flowActivService.findByAgentIdAndTime(agentId, startDate, endDate);

        BigDecimal totalAmount=totalList.stream().map(FlowActiv::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);

        v.setTotalAmount(MathUtils.formatToNumber(totalAmount));


        List<Long> ids = agentContactService.findAllTeamIdsExceptSelf(agentId,channelId);

        List<FlowActiv> subIds = flowActivService.findByAgentIdAndSubIds(agentId, ids, startDate, endDate);

        BigDecimal teamAmount=subIds.stream().map(FlowActiv::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);

        v.setTeamAmount(MathUtils.formatToNumber(teamAmount));
        v.setTeamCount(subIds.size());

        return v;
    }

    @Override
    public Map<String, Object> getMineOtherDetail(MineBenefitDetailDTO dto) {
        boolean startFlag= StringUtils.isBlank(dto.getStartDate());
        boolean endFlag= StringUtils.isBlank(dto.getEndDate());

        if(startFlag!=endFlag){
            throw new BadRequestException("起止时间必须同时选择");
        }
        AgentDTO agentInfo = jwtUserDetailsService.getAgentInfo();


        List<OtherIncome> list = otherIncomeService.findByAgentIdAndTime(agentInfo.getId(), dto.getStartDate(), dto.getEndDate(),dto.getPageNum());

        BigDecimal reduce = list.stream().map(OtherIncome::getAmount).map(e->new BigDecimal(e)).reduce(BigDecimal.ZERO, BigDecimal::add);

        return new HashMap<String, Object>(2){{put("list",list);put("totalAmount",MathUtils.formatToNumber(reduce));}};
    }

}
